<template>
  <div
    class="jump-game"
    @mousedown="handleMouseDown"
    @mouseup="handleMouseUp"
    @touchstart="handleMouseDown"
    @touchend="handleMouseUp"
  >
    <GameBoard
      :character-position="characterPosition"
      :character-rotation="characterRotation"
      :platforms="platforms"
      :game-state="gameState"
    />
    <ScoreBoard
      :score="score"
      :high-score="highScore"
      :game-state="gameState"
    />
    <div v-if="gameState === 'waiting'" class="start-screen">
      <div class="start-message">
        <h2>跳一跳游戏</h2>
        <p>按住鼠标左键或触摸屏幕来蓄力</p>
        <p>松开以跳跃到下一个平台</p>
        <p>点击任意位置开始游戏</p>
      </div>
    </div>
    <GameOver
      v-if="gameState === 'ended'"
      :score="score"
      :high-score="highScore"
      @restart="restartGame"
    />
  </div>
</template>

<script>
import GameBoard from './GameBoard.vue'
import ScoreBoard from './ScoreBoard.vue'
import GameOver from './GameOver.vue'

export default {
  name: 'JumpGame',
  components: {
    GameBoard,
    ScoreBoard,
    GameOver
  },
  data() {
    return {
      characterPosition: { x: 0, y: 0 },
      characterVelocity: { x: 0, y: 0 },
      platforms: [],
      score: 0,
      highScore: 0,
      gameState: 'waiting', // waiting, playing, ended
      jumpPower: 0,
      jumpDirection: 1, // 1 for right, -1 for left
      gameSpeed: 2,
      lastPlatformIndex: 0,
      gravity: 0.3,
      jumpStrength: 12,
      isPressing: false,
      pressStartTime: 0,
      gameLoopId: null,
      characterRotation: 0,
      // 音频相关属性
      audioContext: null,
      oscillator: null,
      gainNode: null
    }
  },
  mounted() {
    this.initGame()
    this.loadHighScore()
    this.initAudio()
  },
  methods: {
    initGame() {
      // 初始化角色位置，确保角色站在第一个平台上
      this.characterPosition = { x: 0, y: -10 } // 角色半径为10，平台在y=0，所以角色中心应在y=-10
      // 重置角色速度
      this.characterVelocity = { x: 0, y: 0 }
      
      // 初始化平台
      this.platforms = [
        { x: 0, y: 0, width: 60, type: 'start' },
        { x: 100, y: -50, width: 60, type: 'normal' },
        { x: 200, y: -100, width: 60, type: 'normal' }
      ]
      
      // 重置游戏状态
      this.score = 0
      this.gameState = 'waiting'
      this.jumpPower = 0
      this.lastPlatformIndex = 0
      // 重置蓄力状态
      this.isPressing = false
      this.pressStartTime = 0
    },
    
    initAudio() {
      try {
        // 创建音频上下文
        this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
      } catch (e) {
        console.error('音频上下文初始化失败:', e);
      }
    },
    
    playChargeSound() {
      if (!this.audioContext) return;
      
      try {
        // 如果已经有正在播放的音效，先停止
        if (this.oscillator) {
          this.oscillator.stop();
          this.oscillator = null;
        }
        
        // 创建振荡器和增益节点
        this.oscillator = this.audioContext.createOscillator();
        this.gainNode = this.audioContext.createGain();
        
        // 配置振荡器
        this.oscillator.type = 'sine'; // 使用正弦波
        this.oscillator.frequency.setValueAtTime(300, this.audioContext.currentTime); // 起始频率300Hz
        
        // 配置增益节点（音量控制）
        this.gainNode.gain.setValueAtTime(0.1, this.audioContext.currentTime); // 初始音量
        
        // 连接节点
        this.oscillator.connect(this.gainNode);
        this.gainNode.connect(this.audioContext.destination);
        
        // 开始播放
        this.oscillator.start();
      } catch (e) {
        console.error('播放蓄力音效失败:', e);
      }
    },
    
    updateChargeSound() {
      if (!this.audioContext || !this.oscillator || !this.gainNode || !this.isPressing) return;
      
      try {
        // 计算蓄力时间
        const pressDuration = Date.now() - this.pressStartTime;
        // 根据蓄力时间调整音效参数，时间越长音调越高、音量越大
        const intensity = Math.min(pressDuration / 1000, 1); // 限制最大值为1
        
        // 调整频率（300Hz到800Hz）
        const frequency = 300 + (500 * intensity);
        this.oscillator.frequency.setValueAtTime(frequency, this.audioContext.currentTime);
        
        // 调整音量（0.1到0.3）
        const volume = 0.1 + (0.2 * intensity);
        this.gainNode.gain.setValueAtTime(volume, this.audioContext.currentTime);
      } catch (e) {
        console.error('更新蓄力音效失败:', e);
      }
    },
    
    stopChargeSound() {
      if (!this.audioContext || !this.oscillator) return;
      
      try {
        // 逐渐降低音量然后停止，避免突兀的停止
        const now = this.audioContext.currentTime;
        this.gainNode.gain.exponentialRampToValueAtTime(0.001, now + 0.1);
        this.oscillator.stop(now + 0.1);
        
        // 清空引用
        this.oscillator = null;
        this.gainNode = null;
      } catch (e) {
        console.error('停止蓄力音效失败:', e);
      }
    },
    
    loadHighScore() {
      const savedHighScore = localStorage.getItem('jumpGameHighScore')
      if (savedHighScore) {
        this.highScore = parseInt(savedHighScore)
      }
    },
    
    saveHighScore() {
      if (this.score > this.highScore) {
        this.highScore = this.score
        localStorage.setItem('jumpGameHighScore', this.highScore)
      }
    },
    
    handleJump() {
      if (this.gameState === 'waiting') {
        this.gameState = 'playing'
        this.startGameLoop()
      } else if (this.gameState === 'playing') {
        this.performJump()
      }
    },
    
    performJump() {
      // 计算跳跃力度
      const pressDuration = Date.now() - this.pressStartTime;
      const power = Math.min(pressDuration / 100, 20); // 最大力度20
      
      // 设置角色速度
      this.characterVelocity.x = power * this.jumpDirection;
      this.characterVelocity.y = -this.jumpStrength;
      
      // 移除这行代码，让小球一直向右跳跃
      // this.jumpDirection *= -1;
    },
    
    startGameLoop() {
      // 启动游戏循环
      const gameLoop = () => {
        if (this.gameState !== 'playing') return;
        
        // 更新角色位置
        this.updateCharacter();
        
        // 检查碰撞
        this.checkCollisions();
        
        // 生成新平台
        this.generatePlatforms();
        
        // 更新蓄力音效
        this.updateChargeSound();
        
        // 继续循环
        this.gameLoopId = requestAnimationFrame(gameLoop);
      };
      
      this.gameLoopId = requestAnimationFrame(gameLoop);
    },
    
    updateCharacter() {
      // 应用重力
      this.characterVelocity.y += this.gravity;
      
      // 更新位置
      this.characterPosition.x += this.characterVelocity.x;
      this.characterPosition.y += this.characterVelocity.y;
      
      // 计算角色旋转角度（基于水平速度）
      this.characterRotation = this.characterVelocity.x * 2;
      
      // 检查是否掉落
      if (this.characterPosition.y > 500) {
        this.endGame();
      }
    },
    
    checkCollisions() {
      // 改进的碰撞检测
      for (let i = 0; i < this.platforms.length; i++) {
        const platform = this.platforms[i];
        const characterBottom = this.characterPosition.y + 10; // 角色半径
        const characterTop = this.characterPosition.y - 10;
        const characterLeft = this.characterPosition.x - 10;
        const characterRight = this.characterPosition.x + 10;
        
        const platformLeft = platform.x - platform.width / 2;
        const platformRight = platform.x + platform.width / 2;
        const platformTop = platform.y - 7;
        const platformBottom = platform.y + 7;
        
        // 检查是否与平台发生碰撞
        if (
          characterRight > platformLeft &&
          characterLeft < platformRight &&
          characterBottom > platformTop &&
          characterTop < platformBottom
        ) {
          // 检查是从上方落下的
          if (this.characterVelocity.y > 0 &&
              this.characterPosition.y < platform.y) {
            // 成功落在平台上
            this.landOnPlatform(i);
            return;
          }
          // 检查是否撞到平台侧面或下方
          else if (this.characterVelocity.y <= 0 &&
                   this.characterPosition.y > platform.y) {
            // 撞到平台底部，反弹
            this.characterVelocity.y = Math.abs(this.characterVelocity.y) * 0.5;
            return;
          }
        }
      }
    },
    
    landOnPlatform(platformIndex) {
      const platform = this.platforms[platformIndex];
      
      // 更新角色位置到平台顶部
      this.characterPosition.y = platform.y - 10; // 角色半径
      this.characterVelocity.y = 0;
      
      // 重置水平速度，防止在平台上滚动
      this.characterVelocity.x = 0;
      
      // 增加得分
      if (platformIndex > this.lastPlatformIndex) {
        // 特殊平台获得额外分数
        if (platform.type === 'special') {
          this.score += 3;
        } else {
          this.score += 1;
        }
        this.lastPlatformIndex = platformIndex;
      }
    },
    
    generatePlatforms() {
      // 改进的平台生成逻辑
      const lastPlatform = this.platforms[this.platforms.length - 1];
      if (lastPlatform.x < this.characterPosition.x + 500) {
        // 根据得分调整难度
        const difficulty = Math.min(this.score / 10, 5);
        
        // 生成新平台
        const minDistance = 60 + difficulty * 5;
        const maxDistance = 120 + difficulty * 10;
        const distance = minDistance + Math.random() * (maxDistance - minDistance);
        
        const newX = lastPlatform.x + distance;
        const minY = lastPlatform.y - 60 - difficulty * 10;
        const maxY = lastPlatform.y + 30 + difficulty * 5;
        const newY = minY + Math.random() * (maxY - minY);
        
        const minWidth = 30;
        const maxWidth = 70 - difficulty * 2;
        const newWidth = Math.max(minWidth, maxWidth - Math.random() * 20);
        
        // 随机生成特殊平台
        const type = Math.random() < 0.1 ? 'special' : 'normal';
        
        this.platforms.push({
          x: newX,
          y: newY,
          width: newWidth,
          type: type
        });
      }
    },
    
    endGame() {
      this.gameState = 'ended';
      if (this.gameLoopId) {
        cancelAnimationFrame(this.gameLoopId);
      }
      this.saveHighScore();
    },
    
    handleMouseDown() {
      if (this.gameState === 'waiting') {
        this.gameState = 'playing';
        this.startGameLoop();
      }
      
      // 无论游戏处于什么状态，只要点击了鼠标就开始蓄力
      if (this.gameState === 'playing') {
        this.isPressing = true;
        this.pressStartTime = Date.now();
        this.playChargeSound(); // 开始蓄力时播放音效
      }
    },
    
    handleMouseUp() {
      if (this.gameState === 'playing' && this.isPressing) {
        this.isPressing = false;
        this.performJump();
        this.stopChargeSound(); // 停止蓄力音效
      }
    },
    
    restartGame() {
      this.saveHighScore();
      this.initGame();
    }
  }
}
</script>

<style scoped>
.jump-game {
  position: relative;
  width: 100%;
  height: 100%;
  background: linear-gradient(to bottom, #87CEEB, #E0F7FA);
  overflow: hidden;
  cursor: pointer;
}

.start-screen {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 100;
}

.start-message {
  background: white;
  padding: 30px;
  border-radius: 15px;
  text-align: center;
  box-shadow: 0 0 30px rgba(0, 0, 0, 0.5);
  max-width: 80%;
}

.start-message h2 {
  color: #4CAF50;
  margin-bottom: 20px;
}

.start-message p {
  font-size: 18px;
  margin: 10px 0;
  color: #333;
}
</style>